﻿using Autofac;
using AutoMapper;
using Serilog;
using SqlSugar;
using System.Linq.Expressions;
using WCS_Core_Configuration;
using WCS_Entity.Dto.TaskDto;
using WCS_Entity.Entity;
using WCS_Repository.Interface;
using WCS_Service.DomianService;
using WCS_Service.DomianService.Interface;
using WCS_Service.Enums;
using WCS_Service.Interface;
using WCS_Service.Models;

namespace WCS_Service.Services
{
    /// <summary>
    /// 任务管理服务
    /// </summary>
    public class TaskService : BaseService<TaskEntity>, ITaskService
    {
        private readonly ITaskRepository _taskRepository;
        private readonly IMapper _mapper;
        private readonly IComponentContext _componentContext;
        private readonly IMapPositionService _mapPositionService;

        #region 构造
        public TaskService(ITaskRepository taskRepository, IMapper mapper, IComponentContext componentContext, IMapPositionService mapPositionService)
        {
            _taskRepository = taskRepository;
            _mapper = mapper;
            _componentContext = componentContext;
            _mapPositionService = mapPositionService;
        }
        #endregion

        public async Task<TaskCreatResultModel> CreateTaskAsync(CreatTaskDto dto)
        {
            TaskCreatResultModel result = new();
            await CreatTaskCheckerAsync("123");
            var flag = await _taskRepository.ExistsAsync(r => r.orderCode == dto.orderCode);
            if (flag)
            {
                Log.Error($"创建订单任务{dto.orderCode}已经存在");
                result.ErrMsg = $"创建订单任务{dto.orderCode}已经存在";
                return result;
            }

            //var targetStn = await MapPositionChecker(dto.areaCode,dto.targetStorage);
            //if (targetStn is null)
            //{
            //    return null;
            //}
            //var sourceStn = await MapPositionChecker(dto.areaCode, dto.sourceStorage);
            var entity = _mapper.Map<TaskEntity>(dto);
            if (entity is null)
            {
                result.ErrMsg = $"创建订单数据错误";
                return result;
            }
            //entity.targetStorage = targetStn;
            //entity.sourceStorage = sourceStn;
            entity.createTime = DateTime.Now;
            entity.agvCode ="";
            entity.errMsg = "";
            
            await _taskRepository.InsertAsync(entity);

            result.taskInfo = _mapper.Map<TaskDto>(entity);
            return result;
        }
        public async Task<TaskDto> UpdateTaskAsync(UpdateTaskDto dto)
        {
            TaskDto result = new();
            var entityInfo = await _taskRepository.QueryByIdAsync(dto.id);
            if (entityInfo is null)
            {
                Log.Error($"编辑任务{dto.id}失败");
                return null;
            }
            if (entityInfo.agvCode != dto.agvCode)
            {
                entityInfo.agvCode = dto.agvCode;
            }
            if (entityInfo.orderCode != dto.orderCode)
            {
                entityInfo.orderCode = dto.orderCode;
            }
            if (entityInfo.taskState != dto.taskState)
            {
                entityInfo.taskState = dto.taskState;
            }
            if (entityInfo.areaCode != dto.areaCode)
            {
                entityInfo.areaCode = dto.areaCode;
            }
            if (entityInfo.rcsTaskCode != dto.rcsTaskCode)
            {
                entityInfo.rcsTaskCode = dto.rcsTaskCode;
            }
            if (entityInfo.taskType != dto.taskType)
            {
                entityInfo.taskType = dto.taskType;
            }
            if (entityInfo.materialType != dto.materialType)
            {
                entityInfo.materialType = dto.materialType;
            }
            if (entityInfo.materialCode != dto.materialCode)
            {
                entityInfo.materialCode = dto.materialCode;
            }
            if (entityInfo.targetStorage != dto.targetStorage)
            {
                entityInfo.targetStorage = dto.targetStorage;
            }
            if (entityInfo.targetRoadWay != dto.targetRoadWay)
            {
                entityInfo.targetRoadWay = dto.targetRoadWay;
            }
            if (entityInfo.sourceStorage != dto.sourceStorage)
            {
                entityInfo.sourceStorage = dto.sourceStorage;
            }
            if (entityInfo.sourceRoadWay != dto.sourceRoadWay)
            {
                entityInfo.sourceRoadWay = dto.sourceRoadWay;
            }
            if (entityInfo.errMsg != dto.errMsg)
            {
                entityInfo.errMsg = dto.errMsg;
            }
            if (entityInfo.isComplete != dto.isComplete)
            {
                entityInfo.isComplete = dto.isComplete;
            }
            if (entityInfo.priority != dto.priority)
            {
                entityInfo.priority = dto.priority;
            }
            if (entityInfo.batchNumber != dto.batchNumber)
            {
                entityInfo.batchNumber = dto.batchNumber;
            }
            if (entityInfo.batchTaskSeq != dto.batchTaskSeq)
            { 
                entityInfo.batchTaskSeq = dto.batchTaskSeq;
            }
            if (entityInfo.Extend1 != dto.Extend1)
            {
                entityInfo.Extend1 = dto.Extend1;
            }
            if (entityInfo.Extend2 != dto.Extend2)
            {
                entityInfo.Extend2 = dto.Extend2;
            }
            if (entityInfo.Extend3 != dto.Extend3)
            {
                entityInfo.Extend3 = dto.Extend3;
            }
            if (entityInfo.Extend4 != dto.Extend4)
            {
                entityInfo.Extend4 = dto.Extend4;
            }
            if (entityInfo.Extend5 != dto.Extend5)
            {
                entityInfo.Extend5 = dto.Extend5;
            }
            entityInfo.updataTime = DateTime.Now;

            await _taskRepository.UpdateAsync(entityInfo);
            result = _mapper.Map<TaskDto>(entityInfo);
            return result;
        }
        public async Task<TaskDto> QueryTaskAsync(int id)
        {
            TaskDto result = new();
            var entityInfo = await _taskRepository.QueryByIdAsync(id);
            if (entityInfo is null)
            {
                Log.Error($"查询指定任务{id}失败");
                return null;
            }
            result = _mapper.Map<TaskDto>(entityInfo);
            return result;
        }
        public async Task<List<TaskDto>> QueryAllTaskAsync()
        {
            List<TaskDto> result = new();
            Expression<Func<TaskEntity, object>> orderEx = p => p.createTime;
            var entityInfos = await _taskRepository.QueryPageAsync(null, orderEx, OrderByType.Desc, 1, 10);
            if (entityInfos is null || !entityInfos.Any())
            {
                Log.Error("查询所有任务失败");
                return null;
            }
            List<Task<TaskDto>> entityList = new List<Task<TaskDto>>();
            foreach (var entityInfo in entityInfos)
            {
                entityList.Add(GetDtoInfoAsync(entityInfo));
            }
            await Task.WhenAll(entityList);
            result = entityList.Select(e => e.Result).ToList();
            return result;
        }
        public async Task<List<TaskDto>> QueryTaskBaseTypeAsync(string type)
        {
            List<TaskDto> result = new();

            Expression<Func<TaskEntity, bool>> expression = eq => eq.taskType == type;
            var entitys = await _taskRepository.QueryListByClauseAsync(expression);
            if (entitys is null || !entitys.Any())
            {
                Log.Error($"查询任务类型{type}的信息不存在");
                return null;
            }
            List<Task<TaskDto>> addInfos = new();
            foreach (var entity in entitys)
            {
                addInfos.Add(GetDtoInfoAsync(entity));
            }
            await Task.WhenAll(addInfos);
            result = addInfos.Select(e => e.Result).ToList();

            return result;
        }
        public async Task<TaskDto> QueryTaskBaseRcsTaskCodeAsync(string code)
        {
            Expression<Func<TaskEntity, bool>> expression = eq => eq.rcsTaskCode == code;
            var entity = await _taskRepository.QueryByClauseAsync(expression);
            if (entity is null)
            {
                Log.Error($"查询rcsTaskCode:{code}的信息不存在");
                return null;
            }
            TaskDto taskDto = new();
            taskDto = _mapper.Map<TaskDto>(entity);
            return taskDto;
        }
        public async Task<bool> DeleteTaskAsync(int id)
        {
            return await _taskRepository.DeleteByIdAsync(id);
        }
        public async Task<List<TaskDto>> QueryCompleteTaskAsync()
        {
            List<TaskDto> result = new();
            Expression<Func<TaskEntity, bool>> expression = eq => eq.isComplete == true;
            var entitys = await _taskRepository.QueryListByClauseAsync(expression);
            if (entitys is null || !entitys.Any())
            {
                Log.Error($"查询已完成的信息不存在");
                return null;
            }
            List<Task<TaskDto>> addInfos = new();
            foreach (var entity in entitys)
            {
                addInfos.Add(GetDtoInfoAsync(entity));
            }
            await Task.WhenAll(addInfos);
            result = addInfos.Select(e => e.Result).ToList();
            return result;
        }
        public async Task<List<TaskDto>> QueryErrTaskAsync()
        {
            List<TaskDto> result = new();
            Expression<Func<TaskEntity, bool>> expression = eq => !string.IsNullOrEmpty(eq.errMsg);
            var entitys = await _taskRepository.QueryListByClauseAsync(expression);
            if (entitys is null || !entitys.Any())
            {
                Log.Error($"查询异常任务的信息不存在");
                return null;
            }
            List<Task<TaskDto>> addInfos = new();
            foreach (var entity in entitys)
            {
                addInfos.Add(GetDtoInfoAsync(entity));
            }
            await Task.WhenAll(addInfos);
            result = addInfos.Select(e => e.Result).ToList();
            return result;
        }
        public async Task<List<TaskDto>> QueryWaitTaskAsync(string type, bool isReadOnly =false)
        {
            List<TaskDto> result = new();
            Expression<Func<TaskEntity, bool>> expression = eq => eq.taskType == type && string.IsNullOrEmpty(eq.agvCode)
            && eq.taskState == TaskState.wait.ToString();
            var entitys = await _taskRepository.QueryListByClauseAsync(expression);
            if (entitys is null || !entitys.Any())
            {
                Log.Information($"查询{type}订单的未分配任务的信息不存在");
                return null;
            }
            List<Task<TaskDto>> addInfos = new();
            foreach (var entity in entitys)
            {
                if (isReadOnly)
                {
                    addInfos.Add(GetDtoInfoAsync(entity)); 
                }
                else
                {
                    addInfos.Add(GetDtoInfoStateChangeAsync(entity)); 
                }
                
            }
            await Task.WhenAll(addInfos);
            result = addInfos.Select(e => e.Result).ToList();
            return result;
        }

        public async Task<List<TaskDto>> QueryWaitTaskBaseAreaCode(string areaCode, bool isReadOnly = false)
        {
            List<TaskDto> result = new();
            Expression<Func<TaskEntity, bool>> expression = eq => eq.areaCode == areaCode && string.IsNullOrEmpty(eq.agvCode)
            && eq.taskState == TaskState.wait.ToString();
            var entitys = await _taskRepository.QueryListByClauseAsync(expression);
            if (entitys is null || !entitys.Any())
            {
                //Log.Information($"查询{areaCode}区域的未分配任务的信息不存在");
                return null;
            }
            List<Task<TaskDto>> addInfos = new();
            foreach (var entity in entitys)
            {
                if (isReadOnly)
                {
                    addInfos.Add(GetDtoInfoAsync(entity));
                }
                else
                {
                    addInfos.Add(GetDtoInfoStateChangeAsync(entity));
                }
            }
            await Task.WhenAll(addInfos);
            result = addInfos.Select(e => e.Result).ToList();
            return result;
        }
        public async Task<bool> UpdateTaskStateAsync(UpdateTaskStateDto dto)
        {
            var entityInfo = await _taskRepository.QueryByIdAsync(dto.id);
            if (entityInfo is null)
            {
                Log.Error($"编辑任务{dto.id}失败");
                return false;
            }
            entityInfo.taskState = dto.state;
            if (dto.state == TaskState.Err.ToString())
            {
                entityInfo.errMsg = dto.errMsg;
            }
            if (!string.IsNullOrEmpty(dto.agvCode) && string.IsNullOrEmpty(entityInfo.agvCode))
            {
                entityInfo.agvCode = dto.agvCode;
            }
            if (!string.IsNullOrEmpty(dto.batchNumber) && string.IsNullOrEmpty(entityInfo.batchNumber))
            {
                entityInfo.batchNumber = dto.batchNumber;
            }
            if (!string.IsNullOrEmpty(dto.batchTaskSeq) && string.IsNullOrEmpty(entityInfo.batchTaskSeq))
            {
                entityInfo.batchTaskSeq = dto.batchTaskSeq;
            }
            entityInfo.updataTime = DateTime.Now;
            await _taskRepository.UpdateAsync(entityInfo);
            return true;
        }
        /// <summary>
        /// 根据执行agvid更新完成任务的状态
        /// </summary>
        /// <param name="agvId"></param>
        /// <returns></returns>
        public async Task<List<string>> UpdateTaskStateBaseAgvIdAsync(string agvId)
        {
            Expression<Func<TaskEntity, bool>> expression = eq => eq.agvCode == agvId
                                                            && eq.taskState == TaskState.execute.ToString();
            var entitys = await _taskRepository.QueryListByClauseAsync(expression);
            if (entitys is null || !entitys.Any())
            {
                Log.Error($"查询{agvId}的执行中任务不存在");
                return null ;
            }
            List<Task<string>> addUpdate = new();
            foreach ( var entity in entitys) 
            {
                addUpdate.Add(UpdateTaskCompleteInfoAsync(entity));
            }
            await Task.WhenAll(addUpdate);
            var result = addUpdate.Where(a => a.Result is not null)?.Select(a => a.Result)?.ToList();
            return result;
        }
        public async Task<TaskDto> UpdateTaskStateBaseRcsTaskIdAsync(string rcsTaskId)
        {
            Expression<Func<TaskEntity, bool>> expression = eq => eq.rcsTaskCode == rcsTaskId;
            var entitys = await _taskRepository.QueryListByClauseAsync(expression);
            var entity = entitys?.FirstOrDefault();
            if (entity is null)
            {
                Log.Error($"查询Rcs的任务id是{rcsTaskId}的执行中任务不存在");
                return null;
            }
            entity.taskState = TaskState.complete.ToString();
            entity.isComplete = true;
            entity.completeTime = DateTime.Now;
            entity.updataTime = DateTime.Now;
            await _taskRepository.UpdateAsync(entity);
            return _mapper.Map<TaskDto>(entity);
        }
        /// <summary>
        /// 回退任务执行AGV为指定agv的执行中任务；
        /// </summary>
        /// <param name="agvId"></param>
        /// <returns></returns>
        public async Task FallbackStateBaseAgvIdAsync(string agvId)
        {
            Expression<Func<TaskEntity, bool>> expression = eq => eq.agvCode == agvId
                                                            && eq.taskState == TaskState.execute.ToString();
            var entitys = await _taskRepository.QueryListByClauseAsync(expression);
            if (entitys is null || !entitys.Any())
            {
                Log.Error($"查询{agvId}的执行中任务不存在-回退");
                return;
            }
            List<Task> addUpdate = new();
            foreach (var entity in entitys)
            {
                addUpdate.Add(UpdateTaskState(entity,TaskState.wait.ToString()));
            }
            await Task.WhenAll(addUpdate);
        }
        /// <summary>
        /// 更新rcs生成的任务编号根据订单号
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        public async Task<TaskDto> UpdateRcsTaskCodeBaseId(int id,string rcsTask)
        {
            var entity = await _taskRepository.QueryByIdAsync(id);
            if (entity is null)
            {
                Log.Error($"查询{id}的执行中任务不存在");
                return null;
            }
            entity.rcsTaskCode = rcsTask;
            entity.updataTime = DateTime.Now;
            await _taskRepository.UpdateAsync(entity);

            return _mapper.Map<TaskDto>(entity);
        }
        #region private
        /// <summary>
        /// 设备地图点位判断
        /// </summary>
        /// <returns></returns>
        private async Task<string> MapPositionChecker(string areaCode ,string binNum)
        {
            if (string.IsNullOrEmpty(areaCode))
            {
                return null;
            }
            var mapPositionInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode,binNum);
            if (mapPositionInfo is null)
            {
                return null;
            }
            return mapPositionInfo.mapPositionCode;
        }
        private async Task UpdateTaskState(TaskEntity entity,string state)
        {
            entity.agvCode = "";
            entity.taskState = state;
            entity.updataTime = DateTime.Now;
            await _taskRepository.UpdateAsync(entity);
        }
        private async Task<string> UpdateTaskCompleteInfoAsync(TaskEntity entity)
        {
            entity.taskState = TaskState.complete.ToString();
            entity.isComplete = true;
            entity.completeTime = DateTime.Now;
            entity.updataTime = DateTime.Now;
            await _taskRepository.UpdateAsync(entity);
            return entity.orderCode;
        }

        private async Task<TaskDto> GetDtoInfoStateChangeAsync(TaskEntity entity)
        {
            entity.taskState = TaskState.execute.ToString();
            await _taskRepository.UpdateAsync(entity);
            return _mapper.Map<TaskDto>(entity);
        }
        private async Task<TaskDto> GetDtoInfoAsync(TaskEntity entity)
        {
            return await Task.Run(() => _mapper.Map<TaskDto>(entity));
        }
        #endregion

        #region 传送带
        private async Task<bool> CreatTaskCheckerAsync(string matType)
        {
            if (!_componentContext.TryResolve<IWCSMainControlManage>(out IWCSMainControlManage instance))
            {
                Log.Error($"主控服务获取失败！");
                return false;
            }
            var service = instance.QueryLineService();
            if (service is null)
            {
                Log.Error($"传送带服务获取失败！");
                return false;
            }
            await service.WriteWarehousingMatTypeAsync(AppSettingsConstVars.Line_3, matType);
            var msg = await service.ReadErrMsg(AppSettingsConstVars.Line_3);
            return true;
        }
        #endregion
    }
}
